package br.com.felix.bmt.web;

import java.util.List;

import org.apache.log4j.Logger;

import br.com.felix.bmt.business.BlogManagement;
import br.com.felix.bmt.exception.ImpossibleToCreateUserException;
import br.com.felix.bmt.model.User;
import br.com.felix.fwt.log.LoggerFactory;
import br.com.felix.fwt.security.exception.UnauthorizedAccessException;
import br.com.felix.fwt.ui.ActionListener;
import br.com.felix.fwt.ui.Button;
import br.com.felix.fwt.ui.Dialog;
import br.com.felix.fwt.ui.Form;
import br.com.felix.fwt.ui.Html;
import br.com.felix.fwt.ui.HtmlWriter;
import br.com.felix.fwt.ui.LabeledTextBox;
import br.com.felix.fwt.ui.Link;
import br.com.felix.fwt.ui.Panel;
import br.com.felix.fwt.ui.PasswordBox;
import br.com.felix.fwt.ui.RadioButton;
import br.com.felix.fwt.ui.RadioGroup;
import br.com.felix.fwt.ui.TabbedPanel;
import br.com.felix.fwt.ui.VerticalPanel;
import br.com.felix.fwt.ui.css.Border;
import br.com.felix.fwt.ui.css.BorderStyle;
import br.com.felix.fwt.ui.css.BorderWidth;
import br.com.felix.fwt.ui.css.Color;
import br.com.felix.fwt.ui.css.Colors;
import br.com.felix.fwt.ui.css.PercentSize;
import br.com.felix.fwt.ui.css.Style;
import br.com.felix.fwt.ui.exception.UserInterfaceInitializationException;
import br.com.felix.fwt.ui.javascript.Message;

/**
 * Home "page".
 * */
public class UserSelection extends BlogManagementForm {

	private static final long serialVersionUID = 3271044207110378365L;
	
	private static Logger logger = LoggerFactory.getLogger(UserSelection.class);
	
	private VerticalPanel vpAlreadyRegisteredUsers = new VerticalPanel();
	
	private TabbedPanel tabWhoAreYou;
	
	private Dialog openedDialog;
	

	@Override
	protected void initializeUserInterface() throws UserInterfaceInitializationException {
	    tabWhoAreYou = new TabbedPanel(this);
		//Writes the title
		HtmlWriter htmlw = new HtmlWriter();
		htmlw.header2("Who are you?");
		
		Panel vpRegisterNewUser = new Panel();

		//Sets the style of the panels that will be inside the TabbedPanel.
		Style width100percent = new Style().width(new PercentSize(100)).padding(10,10,0,10);
		vpAlreadyRegisteredUsers.setStyle(width100percent);
		vpRegisterNewUser.setStyle(width100percent);
		
		Style paddingStyle = new Style().padding(10,10,0,10);

		//Configures the TabbedPanel
		tabWhoAreYou.addTab("Already registered user", vpAlreadyRegisteredUsers);
		tabWhoAreYou.addTab("New user", vpRegisterNewUser);
		tabWhoAreYou.tabStyle.padding(0,10,0,10);
		tabWhoAreYou.setStyle(new Style().width(500));
		tabWhoAreYou.tabFontColor = new Color(200,200,200);
		tabWhoAreYou.focusedTabFontColor = new Color(37,37,37);
		
		//Configures the tab that allows a new user to register. This could be a component :)
		final RadioGroup rdgGender = new RadioGroup();
		final LabeledTextBox txtName = new LabeledTextBox("Name:","");
		final PasswordBox passwd = new PasswordBox();
		
		Button btnRegister = new Button("register!");
		btnRegister.actionListener = new ActionListener("register", true){
			@Override
			public Form actionPerformed() throws UserInterfaceInitializationException, UnauthorizedAccessException {
				return registerNewUser(txtName, rdgGender, passwd);
			}
		};
		
		
		RadioButton rdbMale = new RadioButton("Male", "male");
		RadioButton rdbFemale = new RadioButton("Female", "female");
		rdgGender.addRadioButton(rdbMale, rdbFemale);
		
		Panel panelGender = new Panel();
		panelGender.add(new Html("Gender:"), rdgGender, rdbMale, rdbFemale);

		Panel passwordPanel = new Panel();
        passwordPanel.add(new Html("Password:"), passwd);
		
		
		VerticalPanel content = new VerticalPanel();
		content.add(new Html("Registering is easy as pie! Just say your name and gender, and choose a password!"));
		content.add(txtName);
		content.add(panelGender);
		content.add(passwordPanel);
		content.add(btnRegister);
		content.setRowStyle(paddingStyle);
		vpRegisterNewUser.add(content);
		
		//configures the tab that will display the registered users.
		listRegisteredUsers(tabWhoAreYou, vpAlreadyRegisteredUsers);
		
		VerticalPanel vp = new VerticalPanel();
		vp.add(htmlw);
		vp.add(tabWhoAreYou);
		
		add(vp);
	}



	/**
	 * List the users that are registered in the database.
	 * */
	private void listRegisteredUsers(TabbedPanel tabWhoAreYou, VerticalPanel vpAlreadyRegisteredUsers) {
		Style paddingStyle = new Style().padding(10,10,0,10);
		BlogManagement bm = BlogManagement.instance();
		List<User> lstUsers = bm.getUsers();
		if(lstUsers!= null && lstUsers.size()>0){
			vpAlreadyRegisteredUsers.clearInterface();
			Panel panel;
			Style maleStyle = new Style().color(maleColor).padding(0,5,0,0);
			Style femaleStyle = new Style().color(femaleColor).padding(0,5,0,0);
			Style userStyle;
			for(final User user: lstUsers){
			    userStyle = "male".equals(user.gender)? maleStyle: femaleStyle;
				final Link editLink = new Link("edit");
				editLink.setStyle(userStyle);
				editLink.actionListener = new ActionListener("editBlogOf"+user.name, true){
					@Override
					public Form actionPerformed() throws UserInterfaceInitializationException, UnauthorizedAccessException {
						return openPasswordDialog(user, editLink);
					}
				};
				
				final Link viewLink = new Link("open");
                viewLink.setStyle(userStyle);
                viewLink.actionListener = new ActionListener("openBlogOf"+user.name, true){
                    @Override
                    public Form actionPerformed() throws UserInterfaceInitializationException, UnauthorizedAccessException {
                        return openBlog(user, false);
                    }
                };
                
                panel = new Panel();
                panel.add(new Html(user.name+" "), editLink, viewLink);
				vpAlreadyRegisteredUsers.add(panel);
			}
		}
		else{
			Html htmlMessage = new Html("There are no registered users");
			htmlMessage.setStyle(paddingStyle);
			vpAlreadyRegisteredUsers.add(htmlMessage);
			tabWhoAreYou.showTab("New user");
		}
	}



    private Form openPasswordDialog(final User user, Link link) {
	    if(openedDialog != null){
	        remove(openedDialog);
	    }
	    final Dialog dialog = new Dialog(this, link);
	    openedDialog = dialog;
	    Color color = null;
	    if(user.gender.equals("male")){
	        color = maleColor;
	    }
	    else{
	        color = femaleColor; 
	    }
        dialog.setStyle(new Style().backgroundColor(color).border(new Border().borderStyle(BorderStyle.SOLID).borderWidth(BorderWidth.THIN)));
        
        final PasswordBox passwd = new PasswordBox();
        Button btnLogin = new Button("Login");
        btnLogin.actionListener = new ActionListener(true) {
            @Override
            public Form actionPerformed() throws UserInterfaceInitializationException,UnauthorizedAccessException {
                return login(dialog, user, passwd);
            }
        };
        dialog.add(new Html("Password:"), passwd, btnLogin);
        add(dialog);
        return this;
    }



    protected Form login(Dialog dialog, User user, PasswordBox passwd) throws UserInterfaceInitializationException, UnauthorizedAccessException {
        if(user.password.equals(passwd.getValue())){
            remove(dialog);
            Blog blog = new Blog(user, true);
            blog.initializeForm();
            return blog;
        }
        else{
            executeJavascriptOnce(new Message("Wrong password!"));
        }
        return this;
    }



    /**
	 * Opens the blog of the specified user.
	 * @return the Blog editing form.
	 * */
	private Form openBlog(User u, boolean edit) throws UserInterfaceInitializationException, UnauthorizedAccessException {
		Blog blog = new Blog(u, edit);
		blog.initializeForm();
		return blog;
	}
	
	

	/**
	 * Registers a new user in the database.
	 * @return the Blog editing form if user creation is successful. This instance otherwise.
	 * */
	protected Form registerNewUser(LabeledTextBox txtName, RadioGroup rdgGender, PasswordBox passwd) throws UserInterfaceInitializationException, UnauthorizedAccessException {
		BlogManagement bm = BlogManagement.instance();
		try {
			User usr = new User();
			usr.name = txtName.getValue();
			usr.gender = rdgGender.getValue();
			usr.password = passwd.getValue();
			bm.registerNewUser(usr);
			listRegisteredUsers(tabWhoAreYou, vpAlreadyRegisteredUsers);
			return openBlog(usr, true);
		}
		catch (ImpossibleToCreateUserException e) {
			Message msg = new Message(e.getMessage()+" Please try again.");
			logger.error("Error registering a new user.",e);
			tabWhoAreYou.showTab("New user");
			executeJavascriptOnce(msg);
			return this;
		}
	}
	
	

}
